home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
newsgroups
/
misc.20000114-20000217
/
000166_news@columbia.edu _Thu Jan 27 18:58:17 2000.msg
< prev
next >
Wrap
Internet Message Format
|
2020-01-01
|
8KB
Return-Path: <news@columbia.edu>
Received: from newsmaster.cc.columbia.edu (newsmaster.cc.columbia.edu [128.59.59.30])
by watsun.cc.columbia.edu (8.8.5/8.8.5) with ESMTP id SAA28379
for <kermit.misc@watsun.cc.columbia.edu>; Thu, 27 Jan 2000 18:58:16 -0500 (EST)
Received: (from news@localhost)
by newsmaster.cc.columbia.edu (8.8.5/8.8.5) id SAA22600
for kermit.misc@watsun.cc.columbia.edu; Thu, 27 Jan 2000 18:52:08 -0500 (EST)
X-Authentication-Warning: newsmaster.cc.columbia.edu: news set sender to <news> using -f
From: fdc@watsun.cc.columbia.edu (Frank da Cruz)
Subject: Case Study #17: Fun with Dates and Times
Date: 27 Jan 2000 23:52:05 GMT
Organization: Columbia University
Message-ID: <86qln5$m25$1@newsmaster.cc.columbia.edu>
To: kermit.misc@columbia.edu
C-Kermit 7.0 (and Kermit 95 1.1.18 when it comes out) let you use dates
and times as "native" data types in your commands and scripts. We spoke
about this a little bit in the "How Do I Delete Files More Than a Week
Old?" example but that just skimmed the surface.
I won't bother listing the rules for writing dates and times; they are
spelled out in Section 1.6 of ckermit2.txt. Assuming you know how to
write dates and times, what can you do with them?
You have already seen how they can be used as file selectors. For example,
to send all files that were created in December 1999, you could:
SEND /NOT-BEFORE:1999-12-01 /BEFORE:2000-01-01 *.*
/NOT-BEFORE is almost the same as /AFTER, except /NOT-BEFORE includes the
given date-time (in this case the implied time of 00:00:00 on December 1),
whereas /AFTER excludes it. A fine point indeed! (Of course there is also
a /NOT-AFTER switch, which has the same relationship to /BEFORE.)
To illustrate dates with explicit times, here is a command to send log files
created after noon on the 27th day of January of this year:
SEND /AFTER:{2000-01-27 12:00:00} *.log
A date-time is a single field (or "word") in Kermit syntax, so must be
enclosed in braces if it contains any spaces, as shown above (of course
other variations are possible).
To experiment with date-time formats, use C-Kermit's new DATE command. If
you type "date" by itself, it prints the current date and time. If you
follow it by something, C-Kermit tries to interpret the "something" as a
date and/or time and prints the result (or an error message).
Perhaps the most interesting aspect of C-Kermit's new date-time support is
the ability to do date and time arithmetic. This works in two ways. First,
by using the built-in relative date syntax: YESTERDAY, TOMORROW, +3DAYS,
-6WEEKS, +12YEARS, etc, for example:
DELETE /BEFORE:-2WEEKS *.*
All the built-in symbolic dates are relative to "today", the current date.
You can also perform explicit calculations, such as obtaining a date that is
a given number of days after a given date, or finding out the day of the
week for a given date.
All of C-Kermit's date calculations are based on the Modified Julian Date
(MJD), which is the number of days since 17 November 1858. For dates prior
to 17 Nov 1858, the MJD is negative. MJDs are scalar counting numbers
(unlike the "yyyyddd" format, often but improperly called the Julian date),
so you can do arithmetic on them. For example, if today's MJD is 51570,
then 100 days from today, the MJD will be 51570 + 100 = 51670.
MJDs have some other interesting properties too:
. They can be compared arithmetically. This lets you (for example)
select files that are older (or newer) than some other file, or use
the MJD as a numeric sort key.
. The modulus of the MJD and 7 tells the day of the week (4=Sunday,
5=Monday, 6=Tuesday, 0=Wednesday, ...)
C-Kermit 7.0 includes functions to convert date-time strings to MJD and
vice versa. For example, here's how to get the date 100 days from today:
.\%m := \fmjd(\v(date)) ; Convert today's date to MJD
echo \fmjd2date(\%m+100) ; Add 100 and convert back to a date.
The result is "20000506", or 6 May 2000, which is:
echo \fday(20000506)
Sat
... a Saturday. Did you ever wonder what day of the week you were born?
Ask Kermit (substituting your actual birthday):
echo \fday(27 jan 1958)
Mon
The \fday() function returns the English 3-letter day of the week
abbreviation; \fnday() returns a day-of-week number, 0-6; the argument is
a date-time string. You can use \fmodulus(MJD,7) if you have an MJD.
By the way, the ".<variablename> = <value>" notation is new to C-Kermit 7.0.
The assignment operator can be "=", which does what DEFINE does; ":=" does
what ASSIGN does, and "::=" evaluates the <value> as an arithmetic
expression and then ASSIGNs it to the <variable> (see Section 7.9.1 of the
ckermit2.txt file for details).
C-Kermit's new date conversion and arithmetic functions let us answer
questions like "What is the first Friday after a given date?". Questions
like this come up all the time in data processing. Let's say the variable
\%d contains the "given date":
.\%m ::= \fmjd(\%d)+1 ; Convert day after given date to MJD.
.\%x := \fmod(\%m,7) ; Day of week of day after given date.
.\%y := \fmod(9-\%x,7) ; Days until Friday (0-6)
.\%e := \fmjd2date(\%m+\%y) ; Date of first Friday after given date.
C-Kermit doesn't have a built-in function that returns the date of the first
Friday after a given date, but (as explained in "Using C-Kermit", 2nd Ed,
page 399), you can define your own:
define FRIDAYAFTER {
local \%m \%x \%y
.\%m ::= \fmjd(\%*)+1 ; "\%*" allows for spaces in argument
.\%x := \fmod(\%m,7) ; (see ckermit2.txt Section 7.5)
.\%y := \fmod(9-\%x,7)
return \fmjd2date(\%m+\%y)
}
You can invoke it like this:
\fexec(fridayafter,27 jan 2000)
And you can use it for file selection like this:
delete /before:\fexec(fridayafter,27 jan 1999)
C-Kermit also has another set of functions for dealing with the more common
(but less useful) yyyyddd (year, day of year) format: \fdoy(date-time),
fdoy2date(doy). You can read about them in Section 1.6 of ckermit2.txt.
Arithmetic can also be done with times-of-day. Functions are available to
give the current time in hh:mm:ss notation and as seconds since midnight.
New functions \fntime(hh:mm:ss) converts the given time to seconds since
midnight, and \fn2time(n) converts the given number of seconds since
midnight to hh:mm:ss format. So given a particular time, you can convert it
to seconds-since-midnight, do any desired arithmetic on it, and then convert
the result back to hh:mm:ss format.
To illustrate, let's see What the date and time will be a million seconds
from now:
.\%t := \v(ntime) ; Current time secs since midnight
.\%d := \fmjd(\v(date)) ; MJD of today
incr \%t 1000000 ; Add a million seconds to current time
incr \%d (\%t/86400) ; Extract days and add to MJD
.\%t := \fmod(\%t,86400) ; Remainder is time of day
echo \fmjd2date(\%d) \fn2time(\%t) ; Print the result
(86400 is the number of seconds in a day.)
C-Kermit's date/time functions don't use any platform-specific APIs (except
obviously to obtain the current date and time), so they should work
uniformly everywhere. The range of date arithmetic depends on the integer
size of your computer and the code generated by the C compiler.
And in case you were wondering, the true Julian date is the number of days
since Noon, 1 January 4713 BC (BCE). But this has become a rather large
number (too large for 16- or even 18-bit computer words), so the MJD is used
instead in most computer applications and is, in fact, the internal date
representation in some well-known computer operating systems (but not Unix).
- Frank